<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  1.默认绑定：window this == window; (独立调用指向window)
  2.隐式绑定：对象调用 obj.foo() 谁调用谁绑定 （存在隐式丢失，参数赋值导致绑定失败）
  3.显式绑定：call, apply, bind
  4.new 绑定

  this指向优先级：new > 显式绑定 > 隐式绑定 > 默认绑定

  5.箭头函数：所有绑定规则全部不适用。箭头函数this取决了父环境this（没有this指向）



  <script>
    // let obj = {
    //   a: 1,
    //   foo: function () {
    //     console.log(this); // >obj
    //     /* function test() {
    //       console.log(this); // >window
    //     }
    //     test() */

    //     /* (function test(){
    //       console.log(this); // >window
    //     })() */

    //     function test() {
    //       console.log(this); // >window
    //     }
    //     return test
    //     // 闭包简单定义：当函数执行的时候，导致函数被定义，并抛出
    //   }
    // }
    // obj.foo()()

    // var a = 0;
    // function foo(a, b, c) {
    //   console.log(a, b, c);
    //   console.log(this);
    // }

    // var obj = {
    //   a: 2,
    //   foo: foo
    // }

    // var bar = obj.foo

    // bar() // this>window

    // obj.foo(1, 2, 3)
    // bar.call(obj, 1, 2, 3)
    // bar.apply(obj, [1, 2, 3])
    // bar.bind(obj)(1, 2, 3)

    // 练习题1
    /* var name = 'window'
    var obj1 = {
      name: '1',
      fn1:function () {
        console.log(this.name);
      },
      fn2: () => console.log(this.name),
      fn3: function () {
        return function () {
          console.log(this.name);
        }
      },
      fn4: function () {
        return () => console.log(this.name)
      }
    }

    var obj2 = {
      name: '2'
    }

    obj1.fn1();  // 1
    obj1.fn1.call(obj2) // 2

    obj1.fn2(); // window
    obj1.fn2().call(obj2) // window

    ogj1.fn3()() // window (自调用)
    ogj1.fn3().call(obj2) // 2
    obj1.fn3.call(obj2)() // window

    obj1.fn4()() // 1 箭头函数 父作用域是对象调用
    obj1.fn4().call(obj2) // 1
    obj1.fn4.call(obj2)() // 2 */

    // 练习题2
    function Foo() {
      getName = function() { console.log(1);}
      return this;
    }

    Foo.getName = function() {console.log(2);}

    Foo.prototype.getName = function() {console.log(3);}

    var getName = function() {console.log(4);}
    function getName() {console.log(5);}

    Foo.getName() // 2
    getName() // 4
    Foo().getName() // 1
    getName() // 1





  </script>
</body>

</html>